package com.test.springCloud.controller;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.test.springCloud.mapper.MenuMapper;
import com.test.springCloud.mapper.UserMapper;
import com.test.springCloud.service.UserService;
import com.test.springCloud.utils.CurPool;
import com.test.springCloud.utils.JwtUtil;
import com.test.springCloud.utils.RedisUtils;
import com.test.springCloud.utils.ResultUtils;
import com.test.springcloud.pojo.MenuPojo;
import com.test.springcloud.pojo.RoleNavPojo;
import com.test.springcloud.pojo.RolePojo;
import com.test.springcloud.pojo.UserPojo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户接口
 *
 */
@Controller
@CrossOrigin  //跨域
@RequestMapping("/lxf")
@Slf4j
public class UserController {

    @Resource
    UserService userService;

    @Resource
    UserMapper userMapper;

    @Resource
    MenuMapper mapper;

    @Autowired
    private RedisTemplate redisTemplate;

    private  static final String ACCESS_TOKEN="ACCESS_TOKEN";

    /**
     * 用户注册（注：需要手机号注册）
     * @param req
     * @param request
     * @return
     */
    @PostMapping("/res/register")
    @ResponseBody
    public String register(@RequestBody JSONObject req, HttpServletRequest request){

        JSONObject js = new JSONObject();

        //用户注册
        int size = userService.register(req,request);
        if (size<0){
            js.put("code",4002);
            js.put("msg","用户注册失败，请重新尝试！");
        }else if (size==4003){
            js.put("code",4003);
            js.put("msg","验证码输入不正确，请重新获取！");
        }else if (size==4004){
            js.put("code",4004);
            js.put("msg","该用户已注册！");
        }else {
            js.put("code",200);
            js.put("msg","注册成功！");
        }

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    /**
     * 暂行登录api
     */
    @PostMapping("/userLogin")
    @ResponseBody
    public String userLogin(@RequestBody JSONObject req,HttpServletRequest request){
        JSONObject js = new JSONObject();
        UserPojo user = userService.logins(req);

        if (null==user){
            js.put("code",4001);
            js.put("msg","用户名或密码错误，请重新尝试！");
        }else {
            JSONObject obj = new JSONObject();
            Integer userId = user.getUserId();
            String userName = user.getUserName();

            //token生成
            String token = JwtUtil.createToken(userId, userName);
            //获取当前时间的毫秒值
            String currentTime = String.valueOf(System.currentTimeMillis());
            //拼接存到redis中的Key中
            String accessKey=ACCESS_TOKEN+user.getUserId()+":"+token;
            //往拼接存到redis中的Key存value值
            redisTemplate.opsForValue().set(accessKey,currentTime);
            //设置redis key的过期时间
            redisTemplate.expire(accessKey,60*24, TimeUnit.MINUTES);
            RolePojo role = userService.getRoleById(user.getRoleId());
            //数据装载
            obj.put("account",user.getAccount());
            obj.put("address",user.getAddress());
            obj.put("age",user.getAge());
            obj.put("avatar",user.getAvatar());
            obj.put("nickName",user.getNickName());
            obj.put("sex",user.getSex());
            obj.put("userName",userName);
            obj.put("userId",userId);
            obj.put("token",token);
            obj.put("roleId",role.getRoleId());
            //数据封装
            js.put("code",200);
            js.put("msg","登录成功！");
            js.put("data",obj);
        }

        return JSONObject.toJSONString(js,SerializerFeature.WriteMapNullValue);
    }

    @GetMapping("/getInfo")
    @ResponseBody
    public String getInfo(/*@RequestParam("token") String token,*/HttpServletRequest request){
        JSONObject js = new JSONObject();
        String token = request.getHeader("token");
        //解析token,获取id
        String userId = JwtUtil.getUserId(token);
        int id = Integer.parseInt(userId);
        //查看token是否有效存在
        String accessKey=ACCESS_TOKEN+id+":"+token;
        Long expire = redisTemplate.getExpire(accessKey);
        //token未过期
        if (expire<=0){
            js.put("code",408);
            js.put("msg","token已过期，请重新登录");
        }else{
            UserPojo user = userMapper.getUserById(id);
            //根据用户用户id查询角色
            RolePojo role = userMapper.getRoleById(user.getRoleId());
            //根据角色id查询该角色所拥有的菜单id
            List<RoleNavPojo> menuIdByRoleId = mapper.getMenuIdByRoleId(role.getRoleId());
            List<String> list = new ArrayList<>();
            for (RoleNavPojo r:menuIdByRoleId) {
                //根据menuId查询菜单
                List<MenuPojo> l1 = mapper.getMenuByMenuId(r.getMenuId());
                //循环添加菜单名，形成菜单树
                for (MenuPojo mp: l1) {
                    list.add(mp.getMenuName());
                }
            }
            //数据封装
            js.put("avatar",user.getAvatar());
            js.put("userName",user.getUserName());
            js.put("userId",id);
            js.put("nickName",role.getRoleName());
            js.put("permissions",list);
        }
        return JSONObject.toJSONString(js,SerializerFeature.WriteMapNullValue);
    }

    /**
     * 登陆操作（用户名为手机号码）
     * @param req
     * @return
     */
    @PostMapping("/log/login")
    @ResponseBody
    public String login(@RequestBody JSONObject req){

        JSONObject js = new JSONObject();

        UserPojo user = userService.login(req);//验证登录
        if (null==user){
            js.put("code",4001);
            js.put("msg","用户名或密码错误，请重新尝试！");
        }else {

            Integer userId = user.getUserId();
            String userName = user.getUserName();

            //token生成
            String token = JwtUtil.createToken(userId, userName);
            RolePojo role = userService.getRoleById(user.getRoleId());

            JSONObject obj = new JSONObject();

            obj.put("account",user.getAccount());
            obj.put("address",user.getAddress());
            obj.put("age",user.getAge());
            obj.put("avatar",user.getAvatar());
            obj.put("nickName",user.getNickName());
            obj.put("sex",user.getSex());
            obj.put("userName",userName);
            obj.put("userId",userId);

            js.put("code",200);
            js.put("msg","登录成功！");
            js.put("token",token);
            js.put("userType",role.getRoleName());
            js.put("data",obj);
        }

        return JSONObject.toJSONString(js, SerializerFeature.WriteMapNullValue);
    }

    /**
     * 忘记密码的操作（需要手机验证码来进行密码更改）
     * @param req
     * @param request
     * @return
     */
    @PostMapping("/for/forget")
    @ResponseBody
    public String forget(@RequestBody JSONObject req, HttpServletRequest request){

        return userService.forget(req,request);
    }


    /**
     * 退出登录
     * @param request
     * @return
     */
    @PostMapping("/loginOut")
    @ResponseBody
    public ResultUtils loginOut(@RequestBody JSONObject req, HttpServletRequest request){
        //解析toke
        String token = req.getString("token");
        String userId = JwtUtil.getUserId(token);
        Integer id = Integer.parseInt(userId);
        //将token从redis缓存中移除，达到退出登录的效果
        String accessKey=ACCESS_TOKEN+userId+":"+token;
        redisTemplate.delete(accessKey);
        return ResultUtils.getSuccess("success");
    }

    /**
     * 更新用户信息
     * @param req
     * @param request
     * @return
     */
    @PostMapping("/update/updateUserInfo")
    @ResponseBody
    public ResultUtils updateUserInfo(@RequestBody JSONObject req,HttpServletRequest request){
        return userService.updateUserInfo(req,request);
    }

    /**
     * 此方法是用来发送短信验证的接口
     * @param req
     * @param request
     */
    @PostMapping("/s/send")
    @ResponseBody
    public String send(@RequestBody JSONObject req,HttpServletRequest request)throws Exception{
       return userService.send(req,request);
    }
}
